<template>
  <div>
    <div class="ness">
      <div>
        金属度(metalness)
        <input type="range" min="0" max="1" step="0.01" v-model="options.metalness" />
      </div>
      <div>
        粗糙度(roughness)
        <input type="range" min="0" max="1" step="0.01" v-model="options.roughness" />
      </div>
      <div>
        透明涂层粗糙度(clearcoatRoughness)
        <input type="range" min="0" max="1" step="0.01" v-model="options.clearcoatRoughness" />
      </div>
      <div>
        反射率(reflectivity)
        <input type="range" min="0" max="1" step="0.01" v-model="options.reflectivity" />
      </div>
      <div>
        光泽粗糙度(sheenRoughness)
        <input type="range" min="0" max="1" step="0.01" v-model="options.sheenRoughness" />
      </div>
    </div>
    <div class="map">
      <button v-for="color in colors" :style="`--color:${color}`" @click="setcolor(color)"></button>
      <button class="tt" @click="setmap"></button>
    </div>
    <div id="container"></div>
  </div>
</template>

<script setup lang="ts">
import * as THREE from 'three';
import Create3DCar from './3DCar';
import CreateThree from '@/three/base';
import { onMounted, ref, watch } from 'vue';
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';

const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399'];
const environment = new RGBELoader().load('textures/venice_sunset_1k.hdr');
environment.mapping = THREE.EquirectangularReflectionMapping;
const options = ref({
  metalness: 0.7,
  roughness: 0.8,
  clearcoat: 1,
  reflectivity: 1,
  sheenRoughness: 0.5,
  clearcoatRoughness: 0.03
});
const scene = new CreateThree({
  stats: true,
  environment,
  background: new THREE.Color(0x333333),
  fog: new THREE.Fog(0x333333, 10, 15),
  camera: {
    fov: 40,
    far: 100,
    near: 0.1,
    position: { x: 4.25, y: 1.4, z: -4.5 }
  },
  renderer: {
    antialias: true,
    toneMapping: THREE.ACESFilmicToneMapping,
    toneMappingExposure: 0.85
  },
  control: {
    enableDamping: true,
    maxPolarAngle: Math.PI / 2,
    target: { x: 0, y: 0.5, z: 0 }
  }
});

const carModel = new Create3DCar(options.value, 'mesh/sm_car.gltf');

watch(
  options,
  () => {
    for (const key in options.value) {
      carModel.material[key] = options.value[key] * 1;
    }
  },
  { deep: true }
);
const setcolor = color => {
  carModel.setColor(color);
};
const setmap = () => {
  carModel.createImgeMaterial();
};
const createGride = () => {
  const mesh = new THREE.GridHelper(20, 40, 0xffffff, 0xffffff);
  mesh.material.opacity = 0.1;
  mesh.material.depthWrite = false;
  mesh.material.transparent = true;
  const update = time => {
    mesh.position.x = time % 1;
  };
  return { mesh, update };
};
const grid = createGride();
const animate = () => {
  const time = -performance.now() / 1000;
  grid.update(time);
  scene.update(time);
  carModel.update(time);
  requestAnimationFrame(animate);
};
onMounted(() => {
  scene.bind('#container');
  scene.add(grid.mesh);
  scene.add(carModel.group);
  animate();
});
</script>
<style lang="less" scoped>
input {
  margin: 0;
  outline: none;
}

button {
  appearance: none;
  outline: none;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
}

.ness {
  position: fixed;
  top: 50%;
  left: 20px;
  transform: translateY(-50%);
  color: #fff;
  font-size: 12px;

  div {
    margin: 40px 0;
  }

  input {
    display: block;
    width: 230px;
    --size: 20px;
    --color: #409eff;
  }
}

.map {
  position: fixed;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-self: start;
  line-height: 20px;

  button {
    width: 40px;
    height: 40px;
    margin: 0 10px;
    background: var(--color);
    border-radius: 40px;
    display: block;
    cursor: pointer;
  }

  button.tt {
    transform: rotate(-90deg);
    background: url('texture/decal.png') no-repeat center;
    background-size: 220px 220px;
    background-position: -138px -166px;
  }
}
</style>
